package com.quyunshuo.module.home.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import android.view.animation.DecelerateInterpolator
import android.widget.Scroller
import androidx.core.widget.ScrollerCompat
@Deprecated(message = "练习用的")
@Suppress("DEPRECATION")
class TimeSliderView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    // ================ 配置参数 ================
    // 最小分钟值（起始值）
    private val minMinutes = 5
    // 最大分钟值（结束值）
    private val maxMinutes = 90
    // 刻度线之间的间距（转换为像素）
    private val spacingPx = 12f.dp // 线间距
    // 常规刻度线的高度（转换为像素）
    private val regularHeight = 16f.dp // 常规线高度
    // 主要刻度线的高度（转换为像素）
    private val tickHeight = 24f.dp // 刻度线高度
    // 指示器线的高度（转换为像素）
    private val indicatorHeight = 32f.dp // 指示线高度
    // 刻度线的宽度（转换为像素）
    private val lineWidth = 2f.dp // 线宽

    // ================ 绘画工具 ================
    // 刻度线画笔
    private val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        strokeWidth = lineWidth
        color = Color.GRAY
    }

    // 指示器画笔（红色，比普通刻度线更粗）
    private val indicatorPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        strokeWidth = lineWidth * 2
        color = Color.RED
    }

    // 文本画笔（用于绘制分钟标签）
    private val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.BLACK
        textSize = 12f.dp
    }

    // ================ 手势检测 ================
    // 手势检测器，用于处理触摸事件
    private val gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
        // 标记是否正在滚动
        private var isScrolling = false

        // 当手指按下屏幕时调用
        override fun onDown(e: MotionEvent): Boolean {
            // 停止当前的fling滚动
            isFling = false
            flingScroller.forceFinished(true)
            // 重置滚动状态
            isScrolling = false
            return true
        }

        // 当手指在屏幕上滑动时调用
        override fun onScroll(
            e1: MotionEvent?,
            e2: MotionEvent,
            distanceX: Float,
            distanceY: Float
        ): Boolean {
            // 标记为正在滚动
            isScrolling = true
            // 根据滑动距离移动偏移量
            moveOffset(distanceX)
            return true
        }

        // 当手指快速滑动后抬起时调用（fling效果）
        override fun onFling(
            e1: MotionEvent?,
            e2: MotionEvent,
            velocityX: Float,
            velocityY: Float
        ): Boolean {
            // 启用fling滚动效果
            isFling = true

            // 注释掉的fling实现（需要完善）
            // flingScroller.fling(
            //     0, 0,
            //     -velocityX.toInt(), 0, // x方向为负，因为是从右向左布局
            //     -Int.MAX_VALUE, Int.MAX_VALUE,
            //     0, 0
            // )

            // 请求重绘视图
            invalidate()
            return true
        }

        // 当手指点击屏幕后抬起时调用
        override fun onSingleTapUp(e: MotionEvent): Boolean {
            // 如果不是在滚动中，处理点击事件
            if (!isScrolling) {
                handleClick(e.x)
                return true
            }
            return false
        }
    })

    // ================ 状态变量 ================
    // 所有刻度线的总宽度
    private var totalWidth = 0f
    // X轴偏移量（用于实现滑动效果）
    private var offsetX = 0f
    // 当前选中的分钟值
    private var currentMinute = minMinutes
    // 分钟值变化监听器
    private var minuteChangeListener: ((Int) -> Unit)? = null
    // 上次滚动时间（用于节流）
    private var lastScrollTime = 0L
    // 滚动节流时间（60fps，约16毫秒）
    private val scrollThrottle = 16L // 60fps throttle

    // ================ 滚动辅助 ================
    // Fling滚动控制器（用于实现惯性滚动效果）
    private val flingScroller = Scroller(context, DecelerateInterpolator(1.5f))
    // 标记是否正在进行fling滚动
    private var isFling = false

    // ================ 初始化 ================
    init {
        // 确保视图可以接收触摸事件
        isFocusable = true
        isClickable = true
    }

    // ================ 视图测量 ================
    // 测量视图尺寸
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        // 计算所有刻度线的总宽度（从5分钟到90分钟）
        totalWidth = (maxMinutes - minMinutes) * spacingPx

        // 设置固定高度，确保有足够空间显示指示器和文本
        val height = (indicatorHeight * 2.5f).toInt()
        // 获取视图宽度
        val width = MeasureSpec.getSize(widthMeasureSpec)
        // 设置测量尺寸
        setMeasuredDimension(width, height)
    }

    // ================ 绘制视图 ================
    // 绘制视图内容
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        // 计算视图中心Y坐标
        val centerY = height / 2f
        // 绘制所有时间线（从右向左）
        for (minute in minMinutes..maxMinutes) {
            // 计算线的位置（从右向左布局）
            var xPos = minuteToX(minute) - offsetX  // 修改点1：去除width -

            // 跳过不可见区域（优化性能）
            if (xPos < -spacingPx || xPos > width + spacingPx) continue

            // 根据分钟值确定刻度线高度
            val lineHeight = when {
                // 每10分钟使用主要刻度高度
                minute % 10 == 0 -> tickHeight
                // 每5分钟使用中等刻度高度
                minute % 5 == 0 -> tickHeight * 0.7f
                // 其他分钟使用常规高度
                else -> regularHeight
            }

            // 绘制刻度线
            canvas.drawLine(
                xPos, // X起点
                centerY - lineHeight / 2, // Y起点
                xPos, // X终点
                centerY + lineHeight / 2, // Y终点
                paint // 画笔
            )

            // 绘制分钟标签（每10分钟）
            if (minute % 10 == 0) {
                val text = "$minute"
                // 计算文本宽度（用于居中）
                val textWidth = textPaint.measureText(text)
                // 绘制分钟标签
                canvas.drawText(
                    text, // 文本内容
                    xPos - textWidth / 2, // X位置（居中）
                    centerY - lineHeight - 4f.dp, // Y位置（刻度线上方）
                    textPaint // 文本画笔
                )
            }
        }

        // 绘制当前选择指示器（屏幕中央）
        val indicatorX = width / 2f
        canvas.drawLine(
            indicatorX, // X起点
            centerY - indicatorHeight / 2, // Y起点
            indicatorX, // X终点
            centerY + indicatorHeight / 2, // Y终点
            indicatorPaint // 指示器画笔
        )
    }

    // ================ 触摸事件处理 ================
    // 处理触摸事件
    override fun onTouchEvent(event: MotionEvent): Boolean {
        // 确保处理Fling滚动
        if (flingScroller.computeScrollOffset()) {
            // 更新偏移量
            offsetX = flingScroller.currX.toFloat()
            // 更新当前分钟值
            updateCurrentMinute()
            // 请求重绘
            postInvalidateOnAnimation()
            return true
        }

        // 重置Fling状态
        isFling = false

        // 处理所有触摸事件（通过手势检测器）
        return gestureDetector.onTouchEvent(event) || super.onTouchEvent(event)
    }

    // ================ 辅助方法 ================
    // 处理点击事件
    private fun handleClick(x: Float) {
        // 计算点击的位置对应的分钟
        val clickedMinute = xToMinute(x + offsetX)  // 修改点2：去除width -
        // 确保分钟值在有效范围内
        currentMinute = clickedMinute.coerceIn(minMinutes, maxMinutes)

        // 确保点击后视图正确更新
        offsetX = minuteToX(currentMinute) - (width / 2)  // 修改点3：去除width -
        // 调整偏移量（确保在边界内）
        adjustOffset()
        // 通知监听器分钟值变化
        minuteChangeListener?.invoke(currentMinute)
        // 请求重绘
        invalidate()
    }

    // 移动偏移量（根据滑动距离）
    private fun moveOffset(distanceX: Float) {
        // 防止滚动过快，使用节流
        val now = System.currentTimeMillis()
        if (now - lastScrollTime < scrollThrottle) return
        lastScrollTime = now

        // 更新偏移量（确保在边界内）
        offsetX = (offsetX - distanceX).coerceIn(-totalWidth, totalWidth)
        // 更新当前分钟值
        updateCurrentMinute()
        // 请求重绘
        invalidate()
    }

    // 更新当前分钟值（基于视图中心位置）
    private fun updateCurrentMinute() {
        // 计算视图中心位置
        val centerPos = width / 2f
        // 计算屏幕中心对应的位置
        val screenCenter = centerPos + offsetX  // 修改点4：去除width -
        // 将位置转换为分钟值（确保在有效范围内）
        currentMinute = xToMinute(screenCenter).coerceIn(minMinutes, maxMinutes)
        // 通知监听器分钟值变化
        minuteChangeListener?.invoke(currentMinute)
    }

    // 调整偏移量（确保在边界内）
    private fun adjustOffset() {
        // 确保偏移量在有效范围内
        offsetX = offsetX.coerceIn(-totalWidth, totalWidth)
    }

    // 分钟值转换为X坐标（从右向左布局）
    private fun minuteToX(minute: Int): Float {
        // 分钟转X坐标（从右向左）
        return (minute - minMinutes) * spacingPx
    }

    // X坐标转换为分钟值
    private fun xToMinute(x: Float): Int {
        // X坐标转分钟
        return minMinutes + (x / spacingPx).toInt()
    }

    // ================ 公共接口 ================
    // 设置分钟值变化监听器
    fun setOnMinuteChangedListener(listener: (Int) -> Unit) {
        minuteChangeListener = listener
    }

    // ================ 扩展函数 ================
    // dp转px扩展函数
    val Float.dp: Float get() = this * resources.displayMetrics.density
}